from PyQt5.QtWidgets import QDialog, QProgressBar, QVBoxLayout, QLabel, QPushButton, QHBoxLayout, QTextEdit, QScrollArea
from PyQt5.QtCore import Qt, pyqtSignal, QTimer
import logging
import time
from logger import set_info_redirect_mode

class LogHandler(logging.Handler):
    """自定义日志处理器，将日志发送到进度对话框"""
    def __init__(self, progress_dialog):
        super().__init__()
        self.progress_dialog = progress_dialog
        self.setLevel(logging.DEBUG)  # 修改为处理DEBUG级别及以上的日志，确保所有日志都被捕获
        
    def emit(self, record):
        """处理日志记录"""
        try:
            # 格式化日志消息
            log_message = self.format(record)
            # 发送到进度对话框显示
            self.progress_dialog.add_log_message(log_message, record.levelno)
        except Exception:
            self.handleError(record)

class ProgressDialog(QDialog):
    """进度对话框，用于显示文件加载和处理进度
    
    提供取消功能、动态状态更新和日志显示
    """
    canceled = pyqtSignal()  # 取消信号
    
    def __init__(self, parent=None, cancellable=True):
        super().__init__(parent)
        self.logger = logging.getLogger('frame_analyzer')
        self.is_cancelled = False
        self.is_completed = False
        
        # 设置窗口属性
        self.setWindowTitle("处理中")
        self.setWindowModality(Qt.WindowModal)
        self.setFixedSize(500, 350)  # 增加高度以容纳日志区域
        
        # 设置对话框样式
        self.setStyleSheet("""
            QDialog {
                background-color: white;
            }
            QLabel {
                color: #333333;
            }
            QProgressBar {
                border: 1px solid #BBBBBB;
                border-radius: 5px;
                text-align: center;
                height: 22px;
                margin: 10px 0;
                background-color: #F5F5F5;
            }
            QProgressBar::chunk {
                background-color: #0064c8;
                border-radius: 5px;
            }
            QPushButton {
                background-color: #0064c8;
                color: white;
                border: none;
                border-radius: 4px;
                padding: 6px 12px;
            }
            QPushButton:hover {
                background-color: #0055a5;
            }
            QPushButton:pressed {
                background-color: #00448a;
            }
            QPushButton:disabled {
                background-color: #CCCCCC;
                color: #666666;
            }
            QTextEdit {
                border: 1px solid #BBBBBB;
                border-radius: 5px;
                background-color: #F8F8F8;
                font-family: Consolas, monospace;
                font-size: 12px;
            }
        """)
        
        # 创建布局
        layout = QVBoxLayout()
        
        # 创建状态标签
        self.status_label = QLabel("正在处理...")
        self.status_label.setAlignment(Qt.AlignCenter)
        self.status_label.setStyleSheet("font-size: 14px; margin-bottom: 10px;")
        layout.addWidget(self.status_label)
        
        # 创建进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setValue(0)
        layout.addWidget(self.progress_bar)
        
        # 添加进度详情标签
        self.detail_label = QLabel("")
        self.detail_label.setAlignment(Qt.AlignCenter)
        self.detail_label.setStyleSheet("color: #666666; font-size: 12px;")
        layout.addWidget(self.detail_label)
        
        # 添加日志显示区域
        log_label = QLabel("处理日志:")
        log_label.setStyleSheet("font-weight: bold; margin-top: 10px;")
        layout.addWidget(log_label)
        
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        self.log_text.setFixedHeight(150)  # 设置日志区域高度
        layout.addWidget(self.log_text)
        
        # 添加按钮区域
        button_layout = QHBoxLayout()
        button_layout.addStretch()
        
        # 添加取消按钮
        if cancellable:
            self.cancel_button = QPushButton("取消")
            self.cancel_button.setFixedWidth(100)
            self.cancel_button.clicked.connect(self._on_cancel)
            button_layout.addWidget(self.cancel_button)
        else:
            self.cancel_button = None
            
        layout.addLayout(button_layout)
        
        self.setLayout(layout)
        
        # 设置自定义日志处理器
        self.log_handler = LogHandler(self)
        formatter = logging.Formatter('%(asctime)s - %(levelname)s: %(message)s', '%H:%M:%S')
        self.log_handler.setFormatter(formatter)
        self.logger.addHandler(self.log_handler)
        
        # 保存原始日志级别，在对话框关闭时恢复
        self.original_log_level = self.logger.level
        
        # 启用INFO级别日志重定向到界面，不写入文件
        set_info_redirect_mode(True)
        
    def add_log_message(self, message, level):
        """添加日志消息到日志显示区域
        
        Args:
            message: 日志消息
            level: 日志级别
        """
        # 根据日志级别设置颜色
        if level >= logging.ERROR:
            color = "#FF0000"  # 红色，错误
        elif level >= logging.WARNING:
            color = "#FF8C00"  # 橙色，警告
        elif level >= logging.INFO:
            color = "#006400"  # 深绿色，信息
        else:
            color = "#000000"  # 黑色，调试
            
        # 添加时间戳
        timestamp = time.strftime('%H:%M:%S')
        
        # 添加带样式的消息
        html_message = f"<span style='color:{color};'>[{timestamp}] {message}</span><br>"
        self.log_text.insertHtml(html_message)
        
        # 滚动到底部
        scrollbar = self.log_text.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())
        
    def update_progress(self, value: int, status: str = None, detail: str = None):
        """更新进度和状态
        
        Args:
            value: 进度值(0-100)
            status: 主状态信息
            detail: 详细状态信息
        """
        try:
            self.progress_bar.setValue(value)
            
            if status:
                self.status_label.setText(status)
                self.logger.info(f"进度: {value}%, {status}")
                
            if detail:
                self.detail_label.setText(detail)
                if status:
                    self.logger.debug(f"{status} - {detail}")
            elif status and not detail:
                # 如果有状态但没有详情，将状态设为详情
                self.detail_label.setText(status)
            
            # 设置完成标志，但不自动关闭对话框
            if value >= 100:
                self.logger.info("处理完成")
                self.is_completed = True
                
        except Exception as e:
            self.logger.error(f"更新进度时发生错误: {str(e)}")
            raise
    
    def complete_and_close(self, delay_ms=500):
        """在界面渲染完成后关闭进度对话框
        
        Args:
            delay_ms: 延迟毫秒数，给界面渲染留出时间
        """
        if self.is_completed:
            self.logger.info(f"处理完成，将在{delay_ms}ms后关闭对话框")
            # 使用定时器延迟关闭，确保界面先渲染完毕
            QTimer.singleShot(delay_ms, self.close)
        else:
            self.logger.info("设置完成标志并延迟关闭进度对话框")
            self.is_completed = True
            self.progress_bar.setValue(100)
            self.status_label.setText("处理完成")
            QTimer.singleShot(delay_ms, self.close)
            
    def _on_cancel(self):
        """处理取消按钮点击事件"""
        self.logger.info("用户取消了操作")
        self.is_cancelled = True
        self.status_label.setText("正在取消...")
        self.detail_label.setText("请稍等，正在安全终止操作...")
        if self.cancel_button:
            self.cancel_button.setEnabled(False)
            self.cancel_button.setText("正在取消...")
        self.canceled.emit()
        
    def closeEvent(self, event):
        """重载关闭事件，当用户点击关闭按钮时视为取消操作"""
        if not self.is_cancelled and not self.is_completed and self.progress_bar.value() < 100:
            self._on_cancel()
            # 阻止关闭，直到操作真正结束
            event.ignore()
        else:
            # 恢复INFO日志输出到文件
            set_info_redirect_mode(False)
            # 移除自定义日志处理器
            self.logger.removeHandler(self.log_handler)
            event.accept() 